package vip.ola.pay.channel.chargezfb;

import com.alibaba.fastjson.JSONObject;
import org.apache.commons.lang3.StringUtils;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Controller;
import org.springframework.web.bind.annotation.PostMapping;
import org.springframework.web.bind.annotation.RequestMapping;
import org.springframework.web.bind.annotation.RequestParam;
import org.springframework.web.bind.annotation.ResponseBody;
import vip.ola.core.common.util.MyLog;
import vip.ola.core.common.util.PayDigestUtil;
import vip.ola.core.entity.PayOrder;
import vip.ola.core.entity.PayPassageAccount;
import vip.ola.pay.ctrl.common.BaseController;
import vip.ola.pay.mq.BaseNotify4MchPay;
import vip.ola.pay.service.RpcCommonService;

import java.io.UnsupportedEncodingException;
import java.math.BigDecimal;
import java.text.SimpleDateFormat;
import java.util.*;

import static vip.ola.core.common.constant.Constant.UTF8;
import static vip.ola.core.common.constant.PayConstant.PAY_STATUS_COMPLETE;
import static vip.ola.core.common.constant.PayConstant.PAY_STATUS_SUCCESS;

@RequestMapping("/api/chargezfbtest")
@Controller
public class ChargezfbPayTestController extends BaseController {

    private static final MyLog _log = MyLog.getLog(ChargezfbPayTestController.class);

    @Autowired
    private RpcCommonService rpcCommonService;
    @Autowired
    public BaseNotify4MchPay baseNotify4MchPay;

    @PostMapping("/notifytest")
    @ResponseBody
    public String notify(@RequestParam Map<String,String> map){
        _log.info("接收ChargewxPay回调：" + map.toString());
        String payOrderId = map.get("orderNo");
        PayOrder payOrder = rpcCommonService.rpcPayOrderService.findByPayOrderId(payOrderId);
        Long orderMoney = new BigDecimal(map.get("money")).longValue();
        if (orderMoney.longValue() != payOrder.getAmount()/100){
            return "money fail";
        }
        if(payOrder == null){
            return "order not exist!";
        }
        if (payOrder.getStatus() == PAY_STATUS_SUCCESS || payOrder.getStatus() == PAY_STATUS_COMPLETE) {
            return "success";
        }
        PayPassageAccount payPassageAccount = rpcCommonService.rpcPayPassageAccountService.findById(payOrder.getPassageAccountId());
        if(payPassageAccount == null || StringUtils.isBlank(payPassageAccount.getParam())){
            return "fail";
        }
        String retSign = map.get("sign");
        String sign =getSign(map, payPassageAccount.getPrivateKey());
        _log.info("加签信息：map-{},sign->{}", map, sign );
        if (retSign.equals(sign)){
            if ("success".equals(map.get("status"))){
                int result = rpcCommonService.rpcPayOrderService.updateStatus4Success(payOrder.getPayOrderId());
                _log.info("更新订单状态为支付成功: result={}", result);
                if(result == 1){
                    // 通知业务系统
                    baseNotify4MchPay.doNotify(payOrder, true);
                    return "success";
                }
            }

        }
        return "fail!";
    }



    public static String getSign(Map<String,String> param, String signKey){
        SortedMap<String,String> map = new TreeMap<>(param);
        String str = "";
        map.remove("sign");
        for (Map.Entry<String,String> entry : map.entrySet()){
            if (entry.getValue() == null || "".equals(entry.getValue()) || "sign".equals(entry.getKey()))continue;
            str += entry.getValue();
        }
        return PayDigestUtil.md5(str+signKey,"UTF-8");
    }

    public static void main(String args[]) throws UnsupportedEncodingException {
        String supplyId="2";
        String orderNo = System.currentTimeMillis()+"";
        String company ="cm" ;
        BigDecimal amount =BigDecimal.valueOf(5000);
        String phone="15105180429";
        String notifyUrl = "www.baidu.com";
        String sign="";
//        Map<String ,String>param = new HashMap<>();
//        param.put("supplierId",supplyId);
//        param.put("orderNo",orderNo);
//        param.put("company",company);
//        param.put("amount",amount);
//        param.put("phone",phone);
//        param.put("notifyUrl",notifyUrl);
//        Map<String ,Object>param = new HashMap<>();
//        param.put("userId",supplyId);
//        param.put("userOrderId",orderNo);
//        param.put("phoneType",company);
//        param.put("amount",amount);
//        param.put("phone",phone);
//        SimpleDateFormat df = new SimpleDateFormat("yyyy-MM-dd HH:mm:ss");
//        String createdTime = df.format(System.currentTimeMillis());
//        param.put("createdTime",createdTime);
//        param.put("duration","180");
//        param.put("isSlow","2");
//        param.put("nonce_str","deposit");
//        System.out.println(orderNo);
//        System.out.println(createdTime);
        Map param = new TreeMap();
        param.put("userId", "2");
        param.put("userOrderId", "1639578054091");
        param.put("phone", "15105180429");
        param.put("nonce_str", "deposit");
        System.out.println(getSigns(param,"8251cee0573711eca93683d471678426"));
//        String merchantId="8";
//        String orderNo = String.valueOf(System.currentTimeMillis());
//        String payType ="alipay" ;
//        String money ="30";
//        String notifyUrl = "http://211.99.100.200:8599/api/chargezfb/notify";
//        String sign="";
//        Map<String ,String>param = new HashMap<>();
//        param.put("merchantId",merchantId);
//        param.put("orderNo",orderNo);
//        param.put("payType",payType);
//        param.put("money",money);
//        param.put("notifyUrl",notifyUrl);
//        System.out.println(orderNo);
//        System.out.println(getSing(param,"901d67d12c1bc015033e8d467ddbf64f"));
        Base64.Decoder decoder = Base64.getDecoder();

        System.out.println( new String(decoder.decode("aHR0cDovLzIxMS45OS4xMDAuMTk4OjgwODIvYXBpL3BheQ=="), "UTF-8"));
    }

    public static String getSing(Map<String,String> data, String signKey){
        SortedMap<String,Object> map = new TreeMap(data);
        String str = "";
        for (Map.Entry<String,Object> entry : map.entrySet()){
            if (entry.getValue()!=null && StringUtils.isNotEmpty(entry.getValue().toString()))
                str += entry.getValue();
        }
        return PayDigestUtil.md5(str + signKey,"UTF-8");
    }

    protected static String getSigns(Map<String, Object> map, String key) {
        ArrayList<String> list = new ArrayList<String>();
        for (Map.Entry<String, Object> entry : map.entrySet()) {
            if (null != entry.getValue() && !"".equals(entry.getValue())) {
                if (entry.getValue() instanceof JSONObject) {
                    list.add(entry.getKey() + "=" + PayDigestUtil.getSortJson((JSONObject) entry.getValue()) + "&");
                } else {
                    list.add(entry.getKey() + "=" + entry.getValue() + "&");
                }
            }
        }
        int size = list.size();
        String[] arrayToSort = list.toArray(new String[size]);
        Arrays.sort(arrayToSort, String.CASE_INSENSITIVE_ORDER);
        StringBuilder sb = new StringBuilder();
        for (int i = 0; i < size; i++) {
            sb.append(arrayToSort[i]);
        }
        String result = sb.toString();
        result += "key=" + key;
        _log.info("JdwxPaymentService Sign Before MD5:" + result);
        result = PayDigestUtil.md5(result, UTF8).toUpperCase();
        _log.info("JdwxPaymentService Sign Result:" + result);
        return result;
    }
}
